using IQIGame.Onigao.Framework;
using IQIGame.Onigao.GamePlay;
using NetProtocol.POD;
using System.Collections.Generic;

namespace IQIGame.Onigao.Logic
{
    /// <summary>
    /// 初始化数据
    /// 注意如果是从POD过来的数据，只处理和配置初始化重叠的部分
    /// 也就是LevelEntityCtorData(LevelEntityConfig config)构造函数会赋值，LevelEntityCtorData(LevelEntityPOD pod)构造函数也会赋值的字段
    /// 其他数据在LevelEntity.RefreshExtraFromSaveData()方法里处理
    /// </summary>
    public struct LevelEntityCtorData
    {
        public int mcid;
        public bool isActive;
        public bool isObstacleActive;
        public bool isCheckPointActive;
        public Vector3Int initDirEuler;
        public byte interactType;
        public Vector3Int position;
        public IReadOnlyList<ushort> tags;
        public IReadOnlyList<int> services;
        public List<bool> elevatorFloorActive;
        public int bindEffectResId;
        public int effectBindPoint;
        public int loopAudioCid;

        /// <summary>
        /// 动态创建
        /// </summary>
        /// <param name="mcid"></param>
        /// <param name="isActive"></param>
        /// <param name="isObstacleActive"></param>
        /// <param name="initDirEuler"></param>
        /// <param name="interactType"></param>
        /// <param name="position"></param>
        /// <param name="tags"></param>
        public LevelEntityCtorData(int mcid, bool isActive, bool isObstacleActive, Vector3Int initDirEuler, byte interactType, Vector3Int position, IReadOnlyList<ushort> tags)
        {
            this.mcid = mcid;
            this.isActive = isActive;
            this.isObstacleActive = isObstacleActive;
            this.isCheckPointActive = false;
            this.initDirEuler = initDirEuler;
            this.interactType = interactType;
            this.position = position;
            this.tags = tags;
            this.services = null;
            this.bindEffectResId = 0;
            this.effectBindPoint = 0;
            this.elevatorFloorActive = null;
            this.loopAudioCid = 0;
        }

        /// <summary>
        /// 从配置创建
        /// </summary>
        /// <param name="config"></param>
        public LevelEntityCtorData(LevelEntityConfig config)
        {
            this.mcid = config.id;
            this.isActive = config.isActive;
            this.isObstacleActive = config.isObstacleActive;
            this.initDirEuler = config.initDirEuler;
            this.interactType = config.interactType;
            this.position = config.position;
            this.tags = config.tags;
            this.services = config.services;

            var paramMap = config.paramMap;
            BaseEntityDynamicParam dynParam;

            this.isCheckPointActive = false;
            if (paramMap.TryGetValue(EntityDynamicParamType.CheckPoint, out dynParam))
            {
                var checkPointParam = dynParam as EntityParamCheckPoint;
                this.isCheckPointActive = checkPointParam.isActive;
            }
            this.elevatorFloorActive = null;
            if (paramMap.TryGetValue(EntityDynamicParamType.Elevator, out dynParam))
            {
                var elevatorParam = dynParam as EntityParamElevator;
                elevatorFloorActive = new List<bool>(elevatorParam.floors.Count);
                for (int i = 0; i < elevatorParam.floors.Count; i++)
                {
                    elevatorFloorActive.Add(elevatorParam.floors[i].isActive);
                }
            }
            this.bindEffectResId = 0;
            this.effectBindPoint = 0;
            if (paramMap.TryGetValue(EntityDynamicParamType.BindEffect, out dynParam))
            {
                var bindEffectParam = dynParam as EntityParamBindEffect;
                this.bindEffectResId = bindEffectParam.effectResId;
                this.effectBindPoint = bindEffectParam.bindCid;
            }
            this.loopAudioCid = 0;
            if (paramMap.TryGetValue(EntityDynamicParamType.Audio, out dynParam))
            {
                var audioParam = dynParam as EntityParamAudio;
                this.loopAudioCid = audioParam.defaultAudioCid;
            }
        }

        /// <summary>
        /// 从存档创建
        /// 注意只处理和配置初始化重叠的部分
        /// 也就是LevelEntityCtorData(LevelEntityConfig config)构造函数会赋值，LevelEntityCtorData(LevelEntityPOD pod)构造函数也会赋值的字段
        /// 其他数据在LevelEntity.RefreshExtraFromSaveData()方法里处理
        /// </summary>
        /// <param name="pod"></param>
        public LevelEntityCtorData(LevelEntityPOD pod)
        {
            this.mcid = pod.normal.mcid;
            this.isActive = pod.isActive;
            this.isObstacleActive = pod.normal.isObstacleActive;
            this.isCheckPointActive = pod.normal.isCheckPointActive;
            this.initDirEuler = Vector3Int.FromIntEuler(pod.dirEuler);
            this.interactType = pod.normal.interactType;
            this.position = new Vector3Int(pod.x, pod.y, pod.z);
            this.tags = pod.normal.tags;
            this.services = pod.normal.services;
            this.elevatorFloorActive = pod.normal.elevatorFloorActive;
            this.bindEffectResId = pod.normal.bindEffectRes;
            this.effectBindPoint = pod.normal.effectBindPoint;
            this.loopAudioCid = pod.normal.loopAudio;
        }
    }
}
